import random
import time

#基类
class base_fsm(object):
    
    def enter_state(self,obj):
        raise NotImplementedError()

    def exec_state(self,obj):
        raise NotImplementedError()

    def exit_state(self,obj):
        raise NotImplementedError()

#子类
class run_fsm(base_fsm):
    
    def enter_state(self,obj):
        print("Car[{}] enter run state!".format(id(obj)))

    def exec_state(self,obj):
        print("Car[{}] in run state!".format(id(obj)))

    def exit_state(self,obj):
        print("Car[{}] exit run state!".format(id(obj)))

#
class stop_fsm(base_fsm):
    
    def enter_state(self,obj):
        print("Car[{}] enter stop state!".format(id(obj)))

    def exec_state(self,obj):
        print("Car[{}] in stop state!".format(id(obj)))

    def exit_state(self,obj):
        print("Car[{}] exit stop state!".format(id(obj)))

class Car(object):

    def stop(self):
        print("Stop!!!")

    def go(self):
        print("Goooooooo!!!!!")

    def attach_fsm(self,state,fsm):
        self.fsm = fsm
        self.curr_state = state

    def change_state(self,new_state,new_fsm):
        '''传统转换
        '''
        self.curr_state = new_state
        self.fsm.exit_state(self)
        self.fsm = new_fsm
        self.fsm.enter_state(self)
        self.fsm.exec_state(self)

    def keep_state(self):
        self.fsm.exec_state(self)


class fsm_mgr(object):

    def __init__(self):
        self._fsms = {}
        self._fsms[0] = stop_fsm()
        self._fsms[1] = run_fsm()

    def get_fsm(self,state):
        return self._fsms[state]

    def frame(self,objs,state):
        for obj in objs:
            if state == obj.curr_state:
                obj.keep_state()
            else:
                obj.change_state(state,self._fsms[state])


class World(object):
    def init(self):
        self._cars = []
        self._fsm_mgr = fsm_mgr()
        self.__init_car()

    def __init_car(self):
        for i in range(1):
            car = Car()
            car.attach_fsm(0,self._fsm_mgr.get_fsm(0))
            self._cars.append(car)

    def __frame(self):
        self._fsm_mgr.frame(self._cars,state_factory())

    def run(self):
        while True:
            self.__frame()
            time.sleep(0.5)



def state_factory():
    return random.randint(0,1)

if __name__ == "__main__":
    world = World()
    world.init()
    world.run()




